/* tcpserver.c */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <strings.h>
#include <string>
#include <iostream>
#include <cstdlib>

#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>   /* Standard input/output definitions */
#include <string.h>  /* String function definitions */
#include <unistd.h>  /* UNIX standard function definitions */
#include <fcntl.h>   /* File control definitions */
#include <errno.h>   /* Error number definitions */
#include <termios.h> /* POSIX terminal control definitions */

#include "arduino.h"

using namespace std;

int main()
{
    int PORT = 5000;
    int sock, connected, bytes_recieved , true_var = 1;  
    char send_data [1024] = "test ack"; 
    char recv_data;       
    string recv_data_buff;       
    struct sockaddr_in server_addr,client_addr;    
    socklen_t sin_size;
    int data; // Data to send to Arduino
    
    int port, cfg, flg, fd;
    
    fd = openPort();
    cfg = configPort(fd);
       
    if (fd < 0 || cfg < 0)
    {
        perror("Arduino Port error\n");
        close(fd);
        exit(1);
    }
    
    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
    {
        perror("Socket");
        exit(1);
    }

    if (setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&true_var,sizeof(int)) == -1)
    {
        perror("Setsockopt");
        exit(1);
    }
    
    server_addr.sin_family = AF_INET;         
    server_addr.sin_port = htons(PORT);     
    server_addr.sin_addr.s_addr = INADDR_ANY; 
    bzero(&(server_addr.sin_zero),8); 

    if (bind(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1)
    {
        perror("Unable to bind");
        exit(1);
    }

    if (listen(sock, 5) == -1)
    {
        perror("Listen");
        exit(1);
    }
		
	printf("TCPServer Waiting for client on port %d\n", PORT);
    fflush(stdout);

    while(1)
    {  
        sin_size = sizeof(struct sockaddr_in);
        connected = accept(sock, (struct sockaddr *)&client_addr,&sin_size);
        printf("I got a connection from (%s , %d)\n",
                inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port));
        
        while (1)
        {
            bytes_recieved = recv(connected,&recv_data,1,0);
            fflush(stdout);

            if (recv_data == 'q' || recv_data == 'Q')
            {
                printf("Closing server\n");
                fflush(stdout);
                close(connected);
                
                recv_data = '\0';
                recv_data_buff = "";
                break;
            }
            else if (recv_data == '#')
            {
                recv_data_buff += recv_data;
                data = atoi(recv_data_buff.c_str());
                printf("Sending recv_data_buff = %d to Arduino...\n", data);
                
                flg = arduino(fd, recv_data_buff.c_str());
            
                if(flg < 0)
                {
                    perror("Communication breakdown!\n");
                    //Nack recieved
                    //return -1;
                }
                
                fflush(stdout);
                recv_data = '\0';
                recv_data_buff = "";
            }
            else
            {
                recv_data_buff += recv_data;
            }
            /*
            else 
            {
                printf("\n RECIEVED DATA = %s " , recv_data);
                fflush(stdout);
            }

            recv_data[bytes_recieved] = '\0';
            */
        }
    } 
    
    printf("Closing port and socket\n");
    close(fd);
    close(sock);
    return 0;
} 
